#include "usbkeyboardthread.h"

UsbKeyboardThread::UsbKeyboardThread(QObject *parent) : QObject(parent)
{
    connect(this,&UsbKeyboardThread::startReading,this,&UsbKeyboardThread::readLoop);//通过信号槽将readLoop移到子线程
}

UsbKeyboardThread::~UsbKeyboardThread()
{
    perform(RELEASE_KBDEVICE);
}

void UsbKeyboardThread::perform(receicerFuntion funtion)
{
    selectFuntion = funtion;
}

void UsbKeyboardThread::init()
{
    perform(CONNECT_KBDEVICE);
    this->start();//开始读取
}

void UsbKeyboardThread::start()
{
    if(!running)
    {
        running = true;
        emit startReading();
    }
}

void UsbKeyboardThread::stop()
{
    running = false;
}

void UsbKeyboardThread::pollKeyboardData()
{
    static int interruptTransferTimes;
    if(this->opendevice_flag)
    { //打开设备失败
        qDebug()<<"打开设备失败--";
    }else
    {
        int transferred = 0;
        unsigned char data[64] = {0};
        if(handle)
        {
            usbMutex.lock();
            int ret = libusb_interrupt_transfer(handle, 0x81, data, sizeof(data), &transferred, 700); //306：0x83 ；307：0x81
            usbMutex.unlock();
            if (ret < 0)
            {
                qDebug() << "Failed to interrupt_transfer:" << ret;
                //                qDebug() << "transferred:" << transferred;
                if(ret == -7)
                {
                    //无数据 超时
                    ClaimInterface_flag = 1;//接口声明成功
                    interruptTransferTimes = 0;
                    return;
                }else
                {
                    usbMutex.lock();
                    libusb_release_interface(handle, 0);
                    ret = libusb_claim_interface(handle, 0);
                    usbMutex.unlock();
                    interruptTransferTimes ++;
                    if(interruptTransferTimes > 5)
                    {
                        ClaimInterface_flag = 0;
                        interruptTransferTimes = 0;
                    }
                    return;
                }
            }else
            {
                ClaimInterface_flag = 1;//接口声明成功
                interruptTransferTimes = 0;
                if(transferred == 8/* && SNPassorDetect*/)//键盘数据
                {
                    QByteArray byteArray(reinterpret_cast<char*>(data), 8);
                    emit KBdataReceived(byteArray);
                    start_flag ++;
                    if(start_flag > 6){start_flag = 6;}
                }
                if(transferred == 30)//触摸板数据
                {
                    QByteArray byteArray(reinterpret_cast<char*>(data), 30);
                    emit TPdataReceived(byteArray);
                    touch_count++;
                    touchUp = 0;
                }
                if(transferred == 20 || transferred == 25)//发送软件版本，硬件版本，触摸板版本，Gsonser角度，校准。
                {
                    if(data[0] == 0x5a && data[1] == 0x5a && data[2] == 0x5a && data[3] == 0x50)
                    {
                        IsHeartbeatPacket = true;
                        //        qDebug()<<"lianjie0000000";
                        if(data[4] == 0x01)
                        {
                            KBConnectDongleStatus = true;
                        }
                        else
                        {
                            KBConnectDongleStatus = false;
                        }
                        return;
                    }else
                    {
                        IsHeartbeatPacket = false;
                    }
                    QByteArray byteArray(reinterpret_cast<char*>(data), 20);
                    emit dataReceived(byteArray);
                }
                else if(transferred == 3)//判断连续按下 不用看基本没用
                {
                    QByteArray byteArray(reinterpret_cast<char*>(data), 3);
                    emit KTdataReceived(byteArray);
                    qint64 currentTime = timer.elapsed(); // 获取从调用start()开始的时间，单位为毫秒
                    // 判断时间间隔是否小于10ms
                    if (lastTime1 != 0 && (currentTime - lastTime1) < 15)
                    {
                        is_consecutive = 0;
                    }
                    qDebug()<<"相隔时间为："<<currentTime - lastTime1<<"ms";
                    lastTime1 = currentTime;
                    start_flag ++ ;
                    if(start_flag > 2){start_flag = 2;}
                }
            }
        }
    }
}

int UsbKeyboardThread::connectDevice()
{//重新连接时初始化
//    switch_inter = false;
    start_flag = 0;
    //

    qDebug()<<"连接设备";
    int ret = libusb_init(&context);//初始化libusb库 (libusb_init)
    if (ret < 0) {
        qDebug() << "libusb init error: " << ret;
        return -1;
    }

    // Find the keyboard device
    device = findKeyboardDevice();//调用findKeyboardDevice()查找键盘设备
    if (!device) {
        qDebug() << "Keyboard device not found";
        opendevice_flag = 1;
        ClaimInterface_flag = 0;
        return -2;
    }

    // Open the device
    ret = libusb_open(device, &handle);//如果找到设备，尝试打开设备 (libusb_open)
    if (ret < 0)
    {
        qDebug() << "Failed to open device: " << ret;
        opendevice_flag = 1;
        ClaimInterface_flag = 0;
        return -3;
    }
    // Get the device descriptor
    struct libusb_device_descriptor desc;

    ret = libusb_get_device_descriptor(device, &desc);//获取设备描述符 (libusb_get_device_descriptor)
    if (ret < 0)
    {
        qDebug() << "Failed to get device descriptor: " << ret;
        opendevice_flag = 1;
        ClaimInterface_flag = 0;
        libusb_close(handle);
        return -4;
    }

    ret = libusb_claim_interface(handle, 0);  //306： 1 ；307：0
    if (ret < 0) {
        qDebug() << "Failed to libusb_claim_interface: " << ret;
        opendevice_flag = 1;
        ClaimInterface_flag = 0;
        return -5;
    }

    // Print the device revision number (bcdDevice)
    qDebug() << "Device Revision (bcdDevice):" << QString::number(desc.bcdDevice, 16).toUpper();

    opendevice_flag = 0;
    selectFuntion = POLL_KEYBOARDDATA;
    timer.start();
    return 0;
}

//   查找特定 VID（Vendor ID）和 PID（Product ID）的 USB 键盘设备
libusb_device* UsbKeyboardThread::findKeyboardDevice(){
    //  1. 获取 USB 设备列表
    libusb_device **devices; // 输出参数，存储设备指针数组
    ssize_t count = libusb_get_device_list(context, &devices);// 返回设备数量
    //  2,遍历设备列表
    for (ssize_t i = 0; i < count; i++) {
        struct libusb_device_descriptor desc;  // 获取设备的描述符  （libusb_device_descriptor）
        int ret = libusb_get_device_descriptor(devices[i], &desc); //  存储设备的 VID、PID、版本号等信息
        // qDebug() << "Failed to get device descriptor:: ret" << ret;
        // 3, 检查设备 VID/PID
        if (desc.idVendor == VID && desc.idProduct == PID) {
            //            printDeviceDescriptor(desc);
            return devices[i];   //  如果当前设备的 idVendor 和 idProduct 匹配，直接返回该设备指针。
        }
    }
    //  4. 释放设备列表
    libusb_free_device_list(devices, 1);
    return nullptr;
}

void UsbKeyboardThread:: releaseDevice()
{
    qDebug()<<"释放设备";
    libusb_free_device_list(nullptr, 1);//释放设备列表 (libusb_free_device_list)
    if (handle && opendevice_flag!=1) {
        libusb_release_interface(handle, 0);
        libusb_release_interface(handle, 1);//如果设备已打开，释放接口并关闭设备
        libusb_release_interface(handle, 2);
        libusb_close(handle);
    }
    libusb_exit(context);//退出libusb上下文 (libusb_exit)
}

void UsbKeyboardThread::readLoop()
{
    while(running)
    {
        switch (selectFuntion)
        {
        case POLL_KEYBOARDDATA://接收数据
            pollKeyboardData();
            break;
        case CONNECT_KBDEVICE://连接设备
            connectDevice();
            continue;
        case RELEASE_KBDEVICE://释放设备
            releaseDevice();
            continue;
        case RECONNECT_KBDEVICE://重连设备
            releaseDevice();
            connectDevice();
            continue;
        case SENDDATATO_KBDEVICE://重连设备
            releaseDevice();
            connectDevice();
            continue;
        }
        QThread::msleep(2);//小于1毫秒会断点
    }
}


